#pragma once
#include "Common.hpp"
#include "ObjectPool.hpp"

class ThreadCache
{
public:
    // 申请内存
    // 看ThreadCache的对应freelist当中有没有空间，有的话直接弹出无需加锁，没有就调用FetchFromCentralCache
    void *Allocate(size_t size);
    // 向CentralCache对应大小的桶申请一批指定大小的内存，返回其中一个，其余的链入到ThreadCache的freelist当中
    void *FetchFromCentralCache(size_t index, size_t size);

    // 释放内存
    // 将内存块链入到ThreadCache对应的freelist中，如果该freelist太长就调用ListTooLong
    void Deallocate(void *ptr, size_t size);
    // 将一批内存块归还给CentralCache
    void ListTooLong(FreeList &list, size_t len, size_t size);

    // 析构
    // 线程退出自动将所有占用内存释放给CentralCache
    ~ThreadCache();

private:
    FreeList _freeLists[NFREELISTS];
};

// TLS thread local storage
// #ifdef _WIN32
// static _declspec(thread) ThreadCache *threadCache_pTLS = nullptr;
// #else
// static __thread ThreadCache *threadCache_pTLS = nullptr;
// #endif

struct GC
{
    GC() = default;

    void GetThreadCache(ObjectPool<ThreadCache> *tcPoll)
    {
        _tcPoll = tcPoll;
        _threadCache = tcPoll->New();
    }

    ~GC()
    {
        if (_threadCache != nullptr)
            _tcPoll->Delete(_threadCache);
    }

    ThreadCache *_threadCache = nullptr;
    ObjectPool<ThreadCache> *_tcPoll;
};

// TLS thread local storage
static thread_local struct GC gc_TLS; // C++11新特性
